package syren;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import com.mse.utilities.*;

import java.util.*; 

import org.w3c.dom.*;

public class Domain extends JTabbedPane{

	String displayName;
	boolean openDomainTab;
	HashMap<Object, Object> domainIDvalues;
	HashMap<String, DomainHostArchDef> archDefMap;
	HashMap<String, DomainHost> availHosts, hostDefMap;
	HashMap<String, DomainHostGroup> groupDefMap;
	Document doc;
	Element domainDef;
	ArrayList<DomainHostArchDef> hostArchDefs;
	ArrayList<DomainHost> hostDef;
	ArrayList<DomainHostGroup> hostGroups;
	DefaultListModel modelHost, modelHostArch, modelGroup;
	JList list, groupList;
	JList hostList;
	ArrayList<String> availHostsArrayList;


	public Domain()
	{
		openDomainTab = false;
		archDefMap = new HashMap<String, DomainHostArchDef>();
		availHosts = new HashMap<String, DomainHost>();
		hostArchDefs = new ArrayList<DomainHostArchDef>();
		hostDefMap = new HashMap<String, DomainHost>();
		groupDefMap = new HashMap<String, DomainHostGroup>();
		hostDef = new ArrayList<DomainHost>();
		hostGroups = new ArrayList<DomainHostGroup>();
		domainIDvalues = new HashMap<Object, Object>();
		displayName="";
		availHostsArrayList = new ArrayList<String>();

	}

	public Container create()
	{	
		if(displayName.isEmpty()){
			displayName = JOptionPane.showInputDialog(null, "Enter Domain Display Name:");
			while(displayName.isEmpty()){
				JOptionPane.showMessageDialog(null, "You did not enter a valid domain name.");
				displayName = JOptionPane.showInputDialog(null, "Enter Domain Display Name:");
			}
		}
		this.addTab("Domain ID",domainIdTab());
		this.addTab("Host Architectures",hostArchDefTab());
		this.addTab("Hosts",hostDefTab());
		this.addTab("Host Groups",hostGroupTab());
		openDomainTab=true;
		return this;
	}

	public Container load(String filePath)
	{
		DomainDefinition loadFile;
		try {
			loadFile = new DomainDefinition(filePath);
			com.mse.utilities.Domain theDomain =  loadFile.getDomain();

			DomainId domainID = theDomain.getDomainId();
			displayName = domainID.getDisplayName();
			domainIDvalues.put("DID",domainID.getDID());
			domainIDvalues.put("DomType", domainID.getDomainType());
			domainIDvalues.put("Version", domainID.getVersion());
			Integer major = domainID.getMajor();
			domainIDvalues.put("Major", major.toString());
			Integer minor = domainID.getMinor();
			domainIDvalues.put("Minor", minor.toString());

			hostArchDefs = theDomain.getAllHostArchDefs();
			for(int i=0; i<hostArchDefs.size(); i++){
				DomainHostArchDef arch = hostArchDefs.get(i);
				archDefMap.put(arch.getArchId(), arch);
			}

			hostDef = theDomain.getDomainHosts();
			for(int i=0; i<hostDef.size(); i++){
				DomainHost host = hostDef.get(i);
				hostDefMap.put(host.getHID(), host);
			}
			availHosts.putAll(hostDefMap);

			hostGroups = theDomain.getHostGroups();
			for(int i=0; i<hostGroups.size(); i++){
				DomainHostGroup group = hostGroups.get(i);
				groupDefMap.put(group.getGID(), group);
				Collection<DomainHost> hostsInGroup = group.getAllHosts();
				Iterator<DomainHost> it = hostsInGroup.iterator();
				while(it.hasNext()){
					availHosts.remove(it.next().getHID());
				}
			}

			Container loadDomainTab = create();
			return loadDomainTab;
		} catch (DomainException e) {
			return null;
		}
	}

	private JPanel domainIdTab(){
		String[] dType = {"logical", "physical"};

		JPanel domainDef = new JPanel();
		domainDef.setLayout(new GridLayout(0,2));

		//add DID component and a reference to it added to hashmap
		Label lDID = new Label("Domain Identifier:");
		JTextField tDID = new JTextField(20);
		domainDef.add(lDID);
		domainDef.add(tDID);
		//add type component and a reference to it added to hashmap
		Label lDomType =new Label("Domain Type:");
		JComboBox tDomType=new JComboBox(dType); 
		domainDef.add(lDomType);
		domainDef.add(tDomType);
		//add version component and a reference to it added to hashmap
		Label lVersion = new Label("Version:");
		JTextField tVersion = new JTextField(20);
		domainDef.add(lVersion);
		domainDef.add(tVersion);
		//add major component and a reference to it added to hashmap
		Label lMajor = new Label("Major:");
		JTextField tMajor = new JTextField(20);
		domainDef.add(lMajor);
		domainDef.add(tMajor);
		//add minor component and a reference to it added to hashmap
		Label lMinor = new Label("Minor:");
		JTextField tMinor = new JTextField(20);
		domainDef.add(lMinor);
		domainDef.add(tMinor);


		if(!domainIDvalues.isEmpty()){
			tDID.setText((String)domainIDvalues.get("DID"));
			tDomType.setSelectedItem(domainIDvalues.get("DomType"));
			tVersion.setText((String)domainIDvalues.get("Version"));
			tMajor.setText((String)domainIDvalues.get("Major"));
			tMinor.setText((String)domainIDvalues.get("Minor"));
		}

		domainIDvalues.put("DID",tDID);
		domainIDvalues.put("DomType", tDomType);
		domainIDvalues.put("Version", tVersion);
		domainIDvalues.put("Major", tMajor);
		domainIDvalues.put("Minor", tMinor);

		return domainDef;
	}

	private JPanel hostArchDefTab() {

		JPanel tabContents = new JPanel();
		tabContents.setLayout(new BorderLayout());
		JPanel topArchDefTab = new JPanel();
		topArchDefTab.setLayout(new GridLayout(1,2));
		JPanel bottomArchDefTab = new JPanel();
		bottomArchDefTab.setLayout(new GridLayout(1,2));

		JButton createHostArch = new JButton("Create Host Architecture");
		JButton editHostArch = new JButton("Edit Host Architecture");
		JButton deleteHostArch = new JButton("Delete Host Architecture");

		createHostArch.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				DomainHostArchDef temp =createHostArch();
				if(temp!=null){
					hostArchDefs.add(temp);
					archDefMap.put(temp.getArchId(),temp);
					modelHostArch.addElement(temp.getArchId());
				}
			}
		});

		topArchDefTab.add(createHostArch);
		tabContents.add(topArchDefTab, BorderLayout.NORTH);

		bottomArchDefTab.add(editHostArch);
		bottomArchDefTab.add(deleteHostArch);


		// Create a list that allows adds and removes
		modelHostArch = new DefaultListModel();

		for(int i=0; i<hostArchDefs.size(); i++){
			modelHostArch.addElement(hostArchDefs.get(i).getArchId());
		}

		list = new JList(modelHostArch);
		list.setSelectedIndex(0);
		list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		JScrollPane scrollpane = new JScrollPane(list);
		scrollpane.setVisible(true);
		tabContents.add(scrollpane, BorderLayout.CENTER);
		tabContents.add(bottomArchDefTab, BorderLayout.SOUTH);

		editHostArch.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				try{
					editArch(archDefMap.get(list.getSelectedValue()));
				}catch (NullPointerException npe){
					JOptionPane.showMessageDialog(null, "You must select a Host Architecture Definition to edit.");
				}
			}		
		});

		deleteHostArch.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				String s = (String)list.getSelectedValue();
				if(s!=null){
					int dialogButton = JOptionPane.YES_NO_OPTION;
					int dialogResult =
							JOptionPane.showConfirmDialog (null, "This will delete all hosts and host groups\n" +
									"								that pertain to this architecture.\n\n" +
									"								Continue with delete?","Warning",dialogButton);
					if(dialogResult == JOptionPane.YES_OPTION){
						deleteHostArch(archDefMap.get(list.getSelectedValue()));
					}else return;
				}
				else{
					JOptionPane.showMessageDialog(null, "You must select a Host Architecture to delete.");
				}
			}
		});

		return tabContents;
	}

	protected DomainHostArchDef createHostArch() {
		DomainHostArchDef dhad;
		JTextField archID = new JTextField();
		JTextField osType = new JTextField();
		JTextField osVer = new JTextField();
		JTextField arch = new JTextField();
		JPanel panel = new JPanel(new GridLayout(0, 2));

		panel.add(new JLabel("Architecture ID:"));
		panel.add(archID);
		panel.add(new JLabel("Operating System Type (recommended what is reported by \"uname -s\"):"));
		panel.add(osType);
		panel.add(new JLabel("Operating System Version (recommended what is reported by \"uname -r\"):"));
		panel.add(osVer);
		panel.add(new JLabel("Architecture (recommended what is reported by \"uname -m\"):"));
		panel.add(arch);
		int result = JOptionPane.showConfirmDialog(null, panel, "Create Architecture",
				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
		if (result == JOptionPane.OK_OPTION) {
			dhad = new DomainHostArchDef();
			try{
				if(archDefMap.containsKey(archID.getText())){
					JOptionPane.showMessageDialog(null, "Architecture ID is not unique\n");
					createHost();
				}
				dhad = new DomainHostArchDef(archID.getText(), osType.getText(), 
						osVer.getText(), arch.getText());
			}catch (DomainException de) {
				JOptionPane.showMessageDialog(null, "A field was left empty.");
			}
			return dhad;
		} else {
			return null;
		}
	}

	protected void editArch(DomainHostArchDef selectedValue) {

		JTextField osType = new JTextField(selectedValue.getOsType());
		JTextField osVer = new JTextField(selectedValue.getOsVersion());
		JTextField arch = new JTextField(selectedValue.getArchitecture());
		JPanel panel = new JPanel(new GridLayout(0, 2));

		panel.add(new JLabel("Architecture ID:"));
		panel.add(new JLabel(selectedValue.getArchId()));
		panel.add(new JLabel("Operating System Type (recommended what is reported by \"uname -s\"):"));
		panel.add(osType);
		panel.add(new JLabel("Operating System Version (recommended what is reported by \"uname -r\"):"));
		panel.add(osVer);
		panel.add(new JLabel("Architecture (recommended what is reported by \"uname -m\"):"));
		panel.add(arch);
		int result = JOptionPane.showConfirmDialog(null, panel, "Edit Architecture",
				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
		if (result == JOptionPane.OK_OPTION) {
			if(osType.getText().isEmpty() || osVer.getText().isEmpty() || arch.getText().isEmpty()){
				JOptionPane.showMessageDialog(null, "A field was left empty.");
				editArch(selectedValue);
			}

			selectedValue.setOsType( osType.getText()); 
			selectedValue.setOsVersion(osVer.getText());
			selectedValue.setArchitecture(arch.getText());
			modelHostArch.clear();
			for(int i =0; i<hostArchDefs.size(); i++){
				modelHostArch.addElement(hostArchDefs.get(i).getArchId());
			}
			archDefMap.put(selectedValue.getArchId(), selectedValue);
		}


	}

	protected void deleteHostArch(DomainHostArchDef archDefToRemove) {
		String archIdToRemove = archDefToRemove.getArchId();
		for(int i=0; i<hostDef.size(); i++){
			if(hostDef.get(i).getArchDef().getArchId().equals(archIdToRemove)){
				deleteHostDef(hostDef.get(i).getHID());
				i--;
			}
		}

		hostArchDefs.remove(archDefMap.remove(archDefToRemove.getArchId()));
		modelHostArch.removeElement(archDefToRemove.getArchId());
	}

	private JPanel hostDefTab(){

		JPanel tabContents = new JPanel();
		tabContents.setLayout(new BorderLayout());
		JPanel topArchDefTab = new JPanel();
		JPanel botHostDefTab = new JPanel();
		topArchDefTab.setLayout(new GridLayout(1,2));
		botHostDefTab.setLayout(new GridLayout(1,2));
		JButton createHost = new JButton("Create Host");
		JButton editHost = new JButton("Edit Host");
		JButton deleteHost = new JButton("Delete Host");

		createHost.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				DomainHost temp = createHost();
				if(temp!=null){
					hostDef.add(temp);
					hostDefMap.put(temp.getHID(),temp);
					modelHost.addElement(temp.getHID());
				}
			}

		});

		topArchDefTab.add(createHost);
		tabContents.add(topArchDefTab, BorderLayout.NORTH);
		botHostDefTab.add(editHost);
		botHostDefTab.add(deleteHost);

		// Create a list that allows adds and removes
		modelHost = new DefaultListModel();

		for(int i=0; i<hostDef.size(); i++){
			modelHost.addElement(hostDef.get(i).getHID());
		}

		hostList = new JList(modelHost);
		hostList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

		JScrollPane scrollpane = new JScrollPane(hostList);
		scrollpane.setVisible(true);
		tabContents.add(scrollpane, BorderLayout.CENTER);
		tabContents.add(botHostDefTab, BorderLayout.SOUTH);

		editHost.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {				
				String s = (String)hostList.getSelectedValue();
				if(s!=null){
					editHost(hostDefMap.get(hostList.getSelectedValue()));
				}
				else{
					JOptionPane.showMessageDialog(null, "You must select a Host Definition to edit.");
				}
			}		
		});

		deleteHost.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				String s = (String)hostList.getSelectedValue();
				if(s!=null){
					int dialogButton = JOptionPane.YES_NO_OPTION;
					int dialogResult =
							JOptionPane.showConfirmDialog (null, "This will delete all host groups\n" +
									"								that pertain to this host.\n\n" +
									"								Continue with delete?","Warning",dialogButton);
					if(dialogResult == JOptionPane.YES_OPTION){
						deleteHostDef((String)hostList.getSelectedValue());
					}
					else{
						return;
					}
				}
				else{
					JOptionPane.showMessageDialog(null, "You must select a Host Definition to delete.");
				}				
			}
		});
		return tabContents;
	}

	protected DomainHost createHost() {
		if(!hostArchDefs.isEmpty()){
			DomainHost dh;
			JTextField HID = new JTextField();
			JTextField hostName = new JTextField();
			JComboBox hostArch = new JComboBox();
			for(int i=0; i<hostArchDefs.size();i++){
				hostArch.addItem(hostArchDefs.get(i).getArchId());

			}
			JPanel panel = new JPanel(new GridLayout(0, 2));

			panel.add(new JLabel("Host Identifier:"));
			panel.add(HID);
			panel.add(new JLabel("Host Name:"));
			panel.add(hostName);
			panel.add(new JLabel("Host Architecture:"));
			panel.add(hostArch);
			int result = JOptionPane.showConfirmDialog(null, panel, "Test",
					JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
			if (result == JOptionPane.OK_OPTION) {
				dh = new DomainHost();
				try{
					String archString = hostArch.getSelectedItem().toString();
					if(archDefMap.containsKey(archString)){
						dh = new DomainHost(HID.getText(), hostName.getText(), 
								archDefMap.get(archString));
						if(hostDefMap.containsKey(HID.getText())){
							JOptionPane.showMessageDialog(null, "Host ID is not unique\n");
							createHost();
						}
						availHosts.put(dh.getHID(), dh);
						availHostsArrayList.add(dh.getHID());
					}
				}catch (DomainException de) {
					JOptionPane.showMessageDialog(null, "A field was left empty.");
					createHost();
				}
				return dh;
			} else {
				return null;
			}
		}else{
			JOptionPane.showMessageDialog(null, "Please create at least one host architecture first.");	
			return null;
		}
	}

	protected void editHost(DomainHost selectedValue){

		JTextField HID = new JTextField(selectedValue.getHID());
		JTextField hostName = new JTextField(selectedValue.getHostName());
		JComboBox hostArch = new JComboBox();
		for(int i=0; i<hostArchDefs.size();i++){
			hostArch.addItem(hostArchDefs.get(i).getArchId());

		}


		JPanel panel = new JPanel(new GridLayout(0, 2));

		panel.add(new JLabel("Host Identifier:"));
		panel.add(new JLabel(selectedValue.getHID()));
		panel.add(new JLabel("Host Name:"));
		panel.add(hostName);
		panel.add(new JLabel("Host Architecture:"));
		panel.add(hostArch);

		int result = JOptionPane.showConfirmDialog(null, panel, "Edit Host",
				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);

		if (result == JOptionPane.OK_OPTION) {
			if(hostName.getText().isEmpty()){
				JOptionPane.showMessageDialog(null, "A field was left empty.");
				editHost(selectedValue);
			}
			selectedValue.setHID(HID.getText());
			selectedValue.setHostName(hostName.getText());
			selectedValue.setArchDef(archDefMap.get(hostArch.getSelectedItem().toString()));
			modelHost.clear();
			for(int i =0; i<hostDef.size(); i++){
				modelHost.addElement(hostDef.get(i).getHID());
			}
			hostDefMap.put(selectedValue.getHID(), selectedValue);
		}
	}

	protected void deleteHostDef(String hostId) {
		if(!availHosts.containsKey(hostId)){
			for(int i=0; i<hostGroups.size(); i++){
				if(hostGroups.get(i).hostInGroup(hostId)){
					deleteHostGroup(hostGroups.get(i).getGID());
					break;
				}
			}
		}
		hostDef.remove(availHosts.remove(hostId));
		modelHost.removeElement(hostId);
	}

	private JPanel hostGroupTab() {

		JPanel tabContents = new JPanel();
		tabContents.setLayout(new BorderLayout());
		JPanel topHostGroupTab = new JPanel();
		JPanel botHostGroupTab = new JPanel();
		topHostGroupTab.setLayout(new GridLayout(1,2));
		botHostGroupTab.setLayout(new GridLayout(1,2));
		JButton createHGBut = new JButton("Create Host Group");
		JButton editHGBut = new JButton("Edit Host Group");
		JButton deleteHostGroup = new JButton("Delete Host Group");

		createHGBut.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				DomainHostGroup temp = createHostGroup();
				if(temp!=null){
					hostGroups.add(temp);
					modelGroup.addElement(temp.getGID());
					groupDefMap.put(temp.getGID(),temp);
				}
			}

		});

		topHostGroupTab.add(createHGBut);
		botHostGroupTab.add(editHGBut);
		botHostGroupTab.add(deleteHostGroup);

		tabContents.add(topHostGroupTab, BorderLayout.NORTH);

		// Create a list that allows adds and removes
		modelGroup = new DefaultListModel();

		for(int i=0; i<hostGroups.size(); i++){
			modelGroup.addElement(hostGroups.get(i).getGID());
		}

		groupList = new JList(modelGroup);

		JScrollPane scrollpane = new JScrollPane(groupList);
		scrollpane.setVisible(true);
		tabContents.add(scrollpane, BorderLayout.CENTER);

		tabContents.add(botHostGroupTab, BorderLayout.SOUTH);

		editHGBut.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				DomainHostGroup dhg = groupDefMap.get(groupList.getSelectedValue());
				if(dhg==null)
					JOptionPane.showMessageDialog(null, "You must select a Host Group to edit.");
				else{
					editHostGroup(dhg);
				}
			}	
		});

		deleteHostGroup.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				String s = (String)groupList.getSelectedValue();
				if(s==null){
					JOptionPane.showMessageDialog(null, "You must select a Host Group to delete.");
				}
				else{
					deleteHostGroup(s);
				}
			}
		});

		return tabContents;
	}

	protected DomainHostGroup createHostGroup() {
		if(!availHosts.isEmpty()){
			DomainHostGroup dhg = null;
			JPanel pane = new JPanel(new BorderLayout());
			JPanel panelTop = new JPanel(new GridLayout(0, 2));
			JPanel panelBot = new JPanel(new GridLayout(2, 1));
			JTextField HGID = new JTextField();
			JTextField hostGroupName = new JTextField();

			panelTop.add(new JLabel("Enter Host Group ID:"));
			panelTop.add(HGID);
			panelTop.add(new JLabel("Enter Host Group Name:"));
			panelTop.add(hostGroupName);

			DndTwoLists lists = new DndTwoLists();
			panelBot.add(new JLabel("Available Hosts:                                                        Hosts Currently In Group:"));
			panelBot.add(lists.buildCreate(availHostsArrayList));

			pane.add(panelTop, BorderLayout.NORTH);
			pane.add(panelBot, BorderLayout.SOUTH);

			int result = JOptionPane.showConfirmDialog(null, pane, "Create Host Group",
					JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);

			if (result == JOptionPane.OK_OPTION) {

				try{
					JList groupList = lists.getGroupList();
					if(groupList.getModel().getSize()==0){
						JOptionPane.showMessageDialog(null, "You must place at least one host in a host group.\nPlease try again.");
						return null;
					}
					dhg = new DomainHostGroup(HGID.getText(), hostGroupName.getText());

					JList availList = lists.getAvailList();
					// Get number of items in the list
					int size = availList.getModel().getSize(); // 4
					// Get all item objects
					for (int i=0; i<size; i++) {
						Host im = (Host) availList.getModel().getElementAt(i);
						String item = im.getName();
						if(dhg.hostInGroup(item)){
							availHosts.put(item, dhg.getHostByHostID(item));
							dhg.removeHost(item);
							availHostsArrayList.add(item);
						}
					}



					// Get number of items in the list
					int sizes = groupList.getModel().getSize(); // 4
					// Get all item objects
					for (int i=0; i<sizes; i++) {
						Host im = (Host) groupList.getModel().getElementAt(i);
						String item = im.getName();
						if(!dhg.hostInGroup(item)){
							dhg.addHost(availHosts.remove(item));
							availHostsArrayList.remove(item);
						}
					}
					groupDefMap.put(dhg.getGID(), dhg);
				}
				catch(DomainException de){
					JOptionPane.showMessageDialog(null, "Either the group ID is not unique to this file or a field was left blank.");
				}
			}
			else{
				return null;
			}

			return dhg;

		}
		else{
			JOptionPane.showMessageDialog(null, "You must have at least one available host.");	
			return null;
		}
	}

	protected void editHostGroup(DomainHostGroup hostGroupToEdit) {	
		JPanel pane = new JPanel(new BorderLayout());
		JPanel panelTop = new JPanel(new GridLayout(0, 2));
		JPanel panelBot = new JPanel(new GridLayout(2, 1));
		JTextField HGID = new JTextField(hostGroupToEdit.getGID());
		JTextField hostGroupName = new JTextField(hostGroupToEdit.getName());

		panelTop.add(new JLabel("Enter Host Group ID:"));
		panelTop.add(HGID);
		panelTop.add(new JLabel("Enter Host Group Name:"));
		panelTop.add(hostGroupName);

		String[] hostsToEdit = new String[hostGroupToEdit.getAllHosts().size()];
		Iterator<DomainHost> it = hostGroupToEdit.getAllHosts().iterator();
		for(int i=0; i<hostGroupToEdit.getAllHosts().size(); i++)
			hostsToEdit[i]=it.next().getHID();

		DndTwoLists lists = new DndTwoLists();
		panelBot.add(new JLabel("Available Hosts:                                                        Hosts Currently In Group:"));
		panelBot.add(lists.buildEdit(availHostsArrayList, hostsToEdit));

		pane.add(panelTop, BorderLayout.NORTH);
		pane.add(panelBot, BorderLayout.CENTER);

		int result = JOptionPane.showConfirmDialog(null, pane, "Edit Host Group",
				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);

		if (result == JOptionPane.OK_OPTION) {

			try{
				hostGroupToEdit.setGID(HGID.getText());
				hostGroupToEdit.setName(hostGroupName.getText());

				JList availList = lists.getAvailList();
				// Get number of items in the list
				int size = availList.getModel().getSize(); // 4
				// Get all item objects
				for (int i=0; i<size; i++) {
					Host im = (Host) availList.getModel().getElementAt(i);
					String item = im.getName();
					if(hostGroupToEdit.hostInGroup(item)){
						availHosts.put(item, hostGroupToEdit.getHostByHostID(item));
						hostGroupToEdit.removeHost(item);
						availHostsArrayList.add(item);
					}
				}


				JList groupList = lists.getGroupList();
				// Get number of items in the list
				int sizes = groupList.getModel().getSize(); // 4
				// Get all item objects
				for (int i=0; i<sizes; i++) {
					Host im = (Host) groupList.getModel().getElementAt(i);
					String item = im.getName();
					if(!hostGroupToEdit.hostInGroup(item)){
						hostGroupToEdit.addHost(availHosts.remove(item));
						availHostsArrayList.remove(item);
					}
				}
			}
			catch(DomainException de){
				JOptionPane.showMessageDialog(null, "Either the group ID is not unique to this file or a field was left blank.");
			}
		}
		else{
			return;
		}

		return;
	}

	protected void deleteHostGroup(String groupIdtoRemove) {
		for(int i=0; i<hostGroups.size(); i++){
			if(groupIdtoRemove.equals(hostGroups.get(i).getGID())){
				HashMap <String, DomainHost> hostsToMakeAvail = hostGroups.get(i).getAllHostsHM();
				availHosts.putAll(hostsToMakeAvail);
				Collection<DomainHost> hosts = hostsToMakeAvail.values();
				Iterator<DomainHost> it = hosts.iterator();
				while(it.hasNext()){
					DomainHost dh = it.next();
					it.remove();
					availHostsArrayList.add(dh.getHID());
				}
				hostGroups.remove(i);
				modelGroup.removeElement(groupIdtoRemove);
				return;
			}
		}
	}

	public boolean writeDomainXML(File fileName) {
		boolean success = true;
		try {
			//create a new DomainDefinition document to write to
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			// root element
			doc = docBuilder.newDocument();
			doc.setXmlStandalone(true);
			domainDef = doc.createElement("DomainDef");
			doc.appendChild(domainDef);

			success = xmlWriteDomainID();
			xmlWriteHostArchDef();
			xmlWriteHostDef();
			xmlWriteHostGroup();


			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			transformerFactory.setAttribute("indent-number", 4);  
			Transformer transformer = transformerFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(fileName);
			transformer.transform(source, result);

			if(!success){
				fileName.delete();
			}
			else{
				System.out.println("File saved!");
			}

		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (TransformerException tfe) {
			tfe.printStackTrace();
		}
		return success;
	}

	private boolean xmlWriteDomainID() {
		try{
			//  create DomainID element
			String DIDtextField = ((JTextField)domainIDvalues.get("DID")).getText();
			String domainTypeField = (String) ((JComboBox)domainIDvalues.get("DomType")).getSelectedItem();
			//displayName
			String versionTextField = ((JTextField)domainIDvalues.get("Version")).getText();
			String majorTextField = ((JTextField)domainIDvalues.get("Major")).getText();
			String minorTextField = ((JTextField)domainIDvalues.get("Minor")).getText();
			if(DIDtextField.isEmpty() || domainTypeField.isEmpty() || versionTextField.isEmpty() || majorTextField.isEmpty() || minorTextField.isEmpty()){
				JOptionPane.showMessageDialog(null, "A field was left empty in the Domain ID tab.");
				return false;
			}
			DomainId domainId = new DomainId(DIDtextField, domainTypeField, displayName, versionTextField,
					majorTextField,minorTextField);

			Element domainID = doc.createElement("DomainID");
			domainDef.appendChild(domainID);

			//create and set elements for DomainID
			Element DID = doc.createElement("DID");
			DID.appendChild(doc.createTextNode(domainId.getDID()));
			domainID.appendChild(DID);

			Element domainType = doc.createElement("DomainType");
			domainType.appendChild(doc.createTextNode(domainId.getDomainType()));
			domainID.appendChild(domainType);

			Element displayNameField = doc.createElement("DisplayName");
			displayNameField.appendChild(doc.createTextNode(domainId.getDisplayName()));
			domainID.appendChild(displayNameField);

			Element version = doc.createElement("version");
			version.appendChild(doc.createTextNode(domainId.getVersion()));
			domainID.appendChild(version);

			Element major = doc.createElement("major");
			major.appendChild(doc.createTextNode(majorTextField));
			domainID.appendChild(major);

			Element minor = doc.createElement("minor");
			minor.appendChild(doc.createTextNode(minorTextField));
			domainID.appendChild(minor);

		}catch (DomainException de) {
			
		}
		return true;
	}

	private void xmlWriteHostArchDef() {

		for(int i=0; i<hostArchDefs.size();i++){
			Element hostArch = doc.createElement("HostArchDef");
			domainDef.appendChild(hostArch);
			DomainHostArchDef hostArchDef = hostArchDefs.get(i);

			//create and set elements for DomainID
			Element archID = doc.createElement("ArchID");
			archID.appendChild(doc.createTextNode(hostArchDef.getArchId()));
			hostArch.appendChild(archID);

			Element osType = doc.createElement("osType");
			osType.appendChild(doc.createTextNode(hostArchDef.getOsType()));
			hostArch.appendChild(osType);

			Element osVer = doc.createElement("osVer");
			osVer.appendChild(doc.createTextNode(hostArchDef.getOsVersion()));
			hostArch.appendChild(osVer);

			Element arch = doc.createElement("arch");
			arch.appendChild(doc.createTextNode(hostArchDef.getArchitecture()));
			hostArch.appendChild(arch);
		}
	}

	private void xmlWriteHostDef() {

		for(int i=0; i<hostDef.size();i++){
			Element hostDefine = doc.createElement("HostDef");
			domainDef.appendChild(hostDefine);
			DomainHost hostArchDef = hostDef.get(i);

			Element HID = doc.createElement("HID");
			HID.appendChild(doc.createTextNode(hostArchDef.getHID()));
			hostDefine.appendChild(HID);

			Element hostName = doc.createElement("hostName");
			hostName.appendChild(doc.createTextNode(hostArchDef.getHostName()));
			hostDefine.appendChild(hostName);

			Element hostArch = doc.createElement("HostArch");
			hostArch.appendChild(doc.createTextNode(hostArchDef.getArchDef().getArchId()));
			hostDefine.appendChild(hostArch);
		}

	}

	private void xmlWriteHostGroup() {

		Collection<DomainHost> hosts; 
		DomainHostGroup hostGroupDef;

		for(int i=0; i<hostGroups.size();i++){
			Element hostGroup = doc.createElement("HostGroup");
			domainDef.appendChild(hostGroup);
			hostGroupDef = hostGroups.get(i);

			Element HID = doc.createElement("HGID");
			HID.appendChild(doc.createTextNode(hostGroupDef.getGID()));
			hostGroup.appendChild(HID);

			Element hostName = doc.createElement("groupName");
			hostName.appendChild(doc.createTextNode(hostGroupDef.getName()));
			hostGroup.appendChild(hostName);

			hosts = hostGroupDef.getAllHosts();

			for (DomainHost dh : hosts) {
				Element host = doc.createElement("host");
				host.appendChild(doc.createTextNode(dh.getHID()));
				hostGroup.appendChild(host);
			}
		}
	}

	public String getDisplayName(){
		return displayName;
	}
}
